﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using FileBrowser.Classes;
using FileBrowser.Exceptions;

namespace FileBrowser.Forms
{
    public partial class Form1 : Form
    {
        bool isListBoxClicked = false;//防止listBox被点击时引发treeView的响应函数
        TreeNode initNode;//C:\\文件夹节点
        
        int treeDepth = 0;//0表示C:\\根节点的深度
        int listDepth = 0;

        bool treeEnabled = true;
        bool listEnabled = true;

        public Form1()
        {
            InitializeComponent();
            treeViewCFile.Nodes.Clear();
            string initPath = "C:\\";
            treeViewCFile.Nodes.Add(initPath);
            initNode = treeViewCFile.Nodes[0];
        }

        /// <summary>
        /// 返回文件树结构某节点的层数（C:\\为第0层）
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private int getDepth(TreeNode node)
        {
            if(node == null)
                return 0;
            int result = -1;
            for(TreeNode n= node; n != null; n = n.Parent)
                result++;
            return result;
        }

        /// <summary>
        /// 返回Node节点代表的文件的绝对路径
        /// </summary>
        /// <param name="node">TreeNode类型的节点对象</param>
        /// <returns>string类型的绝对路径</returns>
        private string getFullPathOfNode(TreeNode node)
        {
            string fullPath = node.Text;
            for (TreeNode n = node.Parent; n != null; n = n.Parent)
                fullPath = n.Text+'\\'+fullPath;
            return fullPath;
        }

        /// <summary>
        /// 当TreeView节点被点击后，调用应对函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeViewCFile_AfterSelect(object sender, EventArgs e)
        {
            if (isListBoxClicked)
                return;
            treeDepth = getDepth(treeViewCFile.SelectedNode);
            listDepth = treeDepth;
            TreeNode node = treeViewCFile.SelectedNode;
            string fullPath = getFullPathOfNode(node);
            updateComponents(node, fullPath);
        }

        /// <summary>
        /// 点击ListBox列表的元素，调用应对函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listBoxFiles_DoubleClicked(object sender, EventArgs e)
        {
            isListBoxClicked = true;
            string file=listBoxFiles.SelectedItem.ToString();

            //若选择“...”，返回上一级目录
            if (file.Equals("..."))
            {
                isListBoxClicked = false;
                if (treeDepth == listDepth && treeViewCFile.SelectedNode.Parent != null)
                    treeViewCFile.SelectedNode = treeViewCFile.SelectedNode.Parent;
                else if(treeDepth > listDepth && treeViewCFile.SelectedNode.Parent.Parent != null)
                    treeViewCFile.SelectedNode = treeViewCFile.SelectedNode.Parent.Parent;
                return;
            }

            //treeView被选择的节点只可能为listBox被点击后被选择项的父文件夹或同级非目录文件
            if (treeDepth == listDepth) //假设tree节点是list项的父文件夹，直接检索
            {
                foreach (TreeNode node in treeViewCFile.SelectedNode.Nodes)
                {
                    if (node.Text.Equals(file))
                    {
                        treeViewCFile.SelectedNode = node;
                        break;
                    }
                }
            }
            else if (treeDepth > listDepth)   //那么tree节点是list项的同级非目录文件，通过父节点进行检索
            {
                
                treeViewCFile.SelectedNode = treeViewCFile.SelectedNode.Parent;
                if (treeViewCFile.SelectedNode == null)
                {
                    textBoxInfo.Text = "info: 检索文件时遇到路径异常";
                    isListBoxClicked = false;
                    treeViewCFile.SelectedNode = initNode;
                    return;
                }
                foreach (TreeNode node in treeViewCFile.SelectedNode.Nodes)
                {
                    if (node.Text.Equals(file))
                    {
                        treeViewCFile.SelectedNode = node;
                        break;
                    }
                }
            }

            string fullPath = getFullPathOfNode(treeViewCFile.SelectedNode);
            updateComponents(treeViewCFile.SelectedNode, fullPath);
            isListBoxClicked = false;
            
            treeDepth = getDepth(treeViewCFile.SelectedNode);
            //若被点击的列表项不为目录，则列表深度必定增加
            if (Directory.Exists(fullPath))
                listDepth++;
        }

        /// <summary>
        /// 更新界面或运行程序，
        /// 若是文件夹，则更新界面控件
        /// 若是.txt文件，通过notepad.exe打开文件
        /// 若是.exe文件，运行该文件
        /// </summary>
        /// <param name="node">逻辑上被操作的文件对应的树节点（不一定为SelectedNode）</param>
        /// <param name="fullPath">逻辑上被操作的文件的绝对路径</param>
        private void updateComponents(TreeNode node, String fullPath)
        {
            string type = Path.GetExtension(fullPath);

            //根据文件类型进行相应操作
            if (Directory.Exists(fullPath))
                try
                {
                    listBoxFiles.Items.Clear();
                    List<string> files_FullPath = FolderDealer.GetFilesOfFolder(fullPath);
                    bool contained = false;//判断是否已经加入过该节点下的子文件，防止重复操作
                    if (node.Nodes.Count > 0)
                        contained = true;
                    listBoxFiles.Items.Add("...");
                    foreach (var fileFullPath in files_FullPath)
                    {
                        string filename = Path.GetFileName(fileFullPath);
                        listBoxFiles.Items.Add(filename);
                        if (!contained)
                            node.Nodes.Add(filename);
                    }
                    textBoxInfo.Text = "info: 选择目录" + Path.GetFileName(fullPath);
                }
                catch (AccessPermissionException ex)
                {
                    textBoxInfo.Text = ex.ToString();
                }
            else if (type.Equals(".txt") || type.Equals(".exe"))
            {
                textBoxInfo.Text = "info: 打开文件" + Path.GetFileName(fullPath);
                try
                {
                    FolderDealer.OpenFile(fullPath);
                }
                catch (IOException)
                {
                    textBoxInfo.Text = "info: 打开.txt文件失败";
                }
                catch (Win32Exception)
                {
                    textBoxInfo.Text = "info: 文件路径异常";
                }
            }
            else
            {
                textBoxInfo.Text = "info: 无法打开此类型文件";
            }
        }

        /// <summary>
        /// 点击确认关闭窗口的菜单选项
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripMenuItemCloseConfirm_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// 点击树视图进行交互的菜单选项，
        /// 若交互方式有效，则修改为无效，点击树结构不能打开文件
        /// 若无效，则设置为有效
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripMenuItemTree_Click(object sender, EventArgs e)
        {
            if (treeEnabled)
            {
                toolStripMenuItemTree.Text = "点击树视图进行交互 ×";
                treeViewCFile.AfterSelect -= treeViewCFile_AfterSelect;
            }
            else
            {
                toolStripMenuItemTree.Text = "点击树视图进行交互 √";
                treeViewCFile.AfterSelect += treeViewCFile_AfterSelect;
            }
            treeEnabled ^= true;
        }

        /// <summary>
        /// 点击列表进行交互的菜单选项，
        /// 若交互方式有效，则修改为无效，点击列表项不能打开文件
        /// 若无效，则设置为有效
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripMenuItemList_Click(object sender, EventArgs e)
        {
            if (listEnabled)
            {
                toolStripMenuItemList.Text = "点击列表进行交互 ×";
                listBoxFiles.DoubleClick -= listBoxFiles_DoubleClicked;
            }
            else
            {
                toolStripMenuItemList.Text = "点击列表进行交互 √";
                listBoxFiles.DoubleClick += listBoxFiles_DoubleClicked;
            }
            listEnabled ^= true;
        }
    }
}
